function AStar() {
	this.Dir = [6,9,7,4,1,3];
}

AStar.prototype.initialize = function(section) {
	this.Graph = [];
	for (var i=0;i<24;i++) {
		this.Graph[i] = [];
		for (var j=0;j<80;j++) {
			this.Graph[i][j] = [];
			this.Graph[i][j].x = j;
			this.Graph[i][j].y = i;
			this.Graph[i][j].f = 0;
			this.Graph[i][j].g = 0;
			this.Graph[i][j].h = 0;
			this.Graph[i][j].v = false;
			this.Graph[i][j].c = false;
			this.Graph[i][j].p = null;
			this.Graph[i][j].w = section.walkable(i,j);
		}
	}
}

AStar.prototype.search = function(start,end,section) {
	this.initialize(section);
	
	var openHeap = new BinaryHeap(function(n) {return n.f;});
	openHeap.push(this.Graph[start[0]][start[1]]);
	
	while(openHeap.size() > 0) {
		var n = openHeap.pop();
		
		if ((n.y == end[0]) && (n.x == end[1])) {
			var c = n;
			var ret = [];
			while (c.p) {
				ret.push([c.y,c.x]);
				c = c.p;
			}
			return ret.reverse();
		}
		
		//Close the node.
		n.c = true;
		
		for (var k=0;k<6;k++) {
			var r = section.nextHex([n.y,n.x],this.Dir[k]);
			if (this.Graph[r[0]] && this.Graph[r[0]][r[1]]) {
				r = this.Graph[r[0]][r[1]];
			} else { continue; }
			
			if (r.c || !r.w) { continue;}
			
			var gs = n.g + 1;
			var v = r.v
			
			if (!r.v || gs < r.g) {
				r.v = true;
				r.p = n;
				r.h = r.h || this.manhattan(r,this.Graph[end[0]][end[1]]);
				r.g = gs;
				r.f = r.g + r.h;
				
				if (!v) {
					openHeap.push(r);
				} else {
					openHeap.rescoreElement(r);
				}
			}
		}
	}
	
	return [];
}

AStar.prototype.manhattan = function(n1,n2) { return (Math.abs(n1.x - n2.x) + Math.abs(n1.y - n2.y)); }